<template>
  <div class="app-container">
    <el-row class="wrapper service">
      <el-col :span="24" class="warp-main">
        <div class="el-bar">
          <!--工具条-->
          <el-col :span="24" class="toolbar" style="padding-top:10px">
            <el-form :inline="true">
              <el-form-item>
                <el-button @click="addServiceDialogOpen" icon="el-icon-plus" type="primary">创建服务(slb)</el-button>
              </el-form-item>
              <el-form-item>
                <el-input style="width:250px" v-model="queryKey" placeholder="前端服务名/后端服务名">
                  <i slot="prefix" class="el-input__icon el-icon-search"></i>
                </el-input>
              </el-form-item>
              <el-form-item>
                <el-button @click="serviceQuery" icon="el-icon-search" type="primary">查询</el-button> 共{{serviceData.length}}条记录
              </el-form-item>
            </el-form>
          </el-col>

          <!--数据列表-->
          <el-table v-loading="loadingDataTable" :data="serviceData" highlight-current-row style="width: 100%;">
            <el-table-column type="expand">
              <template slot-scope="scope">
                <!--扩展的数据列表.start-->
                <ServiceAppContainerTable :scope="scope"></ServiceAppContainerTable>
                <!--扩展的数据列表.end-->
              </template>
            </el-table-column>
            <el-table-column width="120" prop="name" label="前端服务" sortable></el-table-column>
            <el-table-column width="80" :formatter="format1" prop="sessionAffinity" label="负载策略" sortable></el-table-column>
            <el-table-column width="80" :formatter="format2" prop="type" label="访问类型" sortable></el-table-column>
            <el-table-column width="120" :formatter="format4" prop="selectors" label="后端服务应用" sortable></el-table-column>
            <el-table-column prop="servicePorts" label="内部入口" sortable>
              <template slot-scope="scope">
                <div v-html="format5(scope.row)">{{ format5(scope.row) }}</div>
              </template>
            </el-table-column>
            <el-table-column  prop="servicePorts" label="外部入口" sortable>
              <template slot-scope="scope">
                <div v-html="format6(scope.row)">{{ format6(scope.row) }}</div>
              </template>
            </el-table-column>
            <el-table-column width="70" prop="creationTimestamp" label="已创建" sortable></el-table-column>
            <el-table-column label="操作" fixed="right" width="160">
              <template slot-scope="scope">
                <el-button icon="el-icon-delete" @click="deleteService(scope.$index, scope.row)" type="danger" size="mini">删除</el-button>
                <el-button icon="el-icon-edit" @click="updateServiceDialogOpen(scope.$index, scope.row)" type="primary" size="mini">修改</el-button>
              </template>
            </el-table-column>
          </el-table>

          <!--新增/修改服务-->
          <el-dialog :title="serviceTitle" :visible.sync="serviceAddVisible" :close-on-click-modal="true" width="700px">
            <el-form :inline="true" ref="f1" :model="form1" status-icon label-width="80px" class="form-top">
              <el-form-item label="后端应用" prop="backendApp">
                <el-tooltip class="item" effect="dark" content="针对未创建的后端应用可以先创建前端服务,之后再去创建对应的后端应用,这里先输入待创建应用的名称" placement="top-start">
                  <el-input @blur="appNameInputBlur" :disabled="baseBackendAppSelect" v-model="form1.backendApp" style="width:140px" placeholder="输入后端应用名称"></el-input>
                </el-tooltip>
              </el-form-item>
              <el-form-item v-show="vShow" prop="baseBackendAppSelect" label-width="130px" label="基于后端应用选择">
                <el-switch v-model="baseBackendAppSelect"></el-switch>
              </el-form-item>
              <el-form-item v-show="vShow" label="" prop="apps">
                <el-select :disabled="!baseBackendAppSelect" @change="appSelectChange" style="width:200px;" v-model="form1.selectAppNameKube" placeholder="后端应用">
                  <el-option v-for="item in form1.apps" :key="item.appNameKube" :label="item.appName" :value="item.appNameKube">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="服务名称" prop="name">
                <el-input :disabled="serviceNameDisable" v-model="form1.name" style="width:508px" placeholder="请输入服务名称"></el-input>
              </el-form-item>
              <el-form-item label="负载策略" prop="type">
                <el-select style="width:212px;" v-model="form1.sessionAffinity" placeholder="负载策略">
                  <el-option label="轮询" value="None"></el-option>
                  <el-option label="客户端session" value="ClientIP"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="服务类型" prop="type">
                <el-select style="width:212px;" v-model="form1.type" placeholder="服务类型">
                  <el-option label="内部访问" value="ClusterIP"></el-option>
                  <el-option label="外部访问" value="NodePort"></el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="前端服务端口" label-width="100px" />
              <el-form-item label="后端容器端口" label-width="100px" />
              <el-form-item label="协议" />
              <el-form-item label="节点端口自动生成" label-width="130px" style="margin-left:30px" />
              <el-form-item label="节点端口" label-width="90px" />
              <el-form-item v-for="(servicePort, index) in form1.servicePorts" :key="servicePort.key" :prop="'servicePorts.' + index + '.value'">
                <el-input style="width:80px;margin-left:10px" v-model="servicePort.port"></el-input>
                <el-input style="width:90px;margin-left:10px" v-model="servicePort.targetPort"></el-input>
                <el-select style="width:90px;margin-left:10px" v-model="servicePort.protocal" placeholder="协议">
                  <el-option label="TCP" value="TCP"></el-option>
                  <el-option label="UDP" value="UDP"></el-option>
                </el-select>
                <el-switch :disabled="form1.type=='ClusterIP'" style="width:70px;margin-left:45px" v-model="servicePort.nodePortAutoCreate"></el-switch>
                <el-tooltip class="item" effect="dark" content="指定端口范围: 5000-32767" placement="top-start">
                  <el-input :disabled="form1.type=='ClusterIP'||servicePort.nodePortAutoCreate" style="width:80px;margin-left:28px" v-model="servicePort.nodePort"></el-input>
                </el-tooltip>
                <el-button type="danger" @click.prevent="removeDomain(servicePort)">删除</el-button>
              </el-form-item>
            </el-form>
            <div>
              <el-button @click="addDomain" type="primary">+ 新增端口映射</el-button>
            </div>
            <div slot="footer" class="dialog-footer">
              <el-button class="iconfont icon-chehui" @click="serviceAddVisible=false">取消</el-button>
              <el-button class="iconfont icon-fuxuan" @click="addOrUpdateServiceSubmit" type="primary">确定</el-button>
            </div>
          </el-dialog>
        </div>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import ServiceAppContainerTable from "@/components/appCenter/serviceManager/serviceAppContainerTable";
import { Notification } from 'element-ui';
export default {
  components: { ServiceAppContainerTable },
  data() {
    return {
      vShow: true,//
      //查询关键词
      queryKey: '',
      //节点数据
      serviceData: [
      ],
      // 任务查询遮罩
      loadingDataTable: true,
      serviceAddVisible: false,
      serviceTitle: "修改服务(slb)",
      serviceNameDisable: true,
      baseBackendAppSelect: true,//基于后端应用选择
      form1: {//服务form
        selectAppNameKube: "",
        backendApp: "",//后端应用
        apps: [],
        type: 'ClusterIP',
        name: '',//服务名称
        sessionAffinity: 'None',//服务负载均衡策略
        servicePorts: [{
          name: '',//端口名称
          protocal: "TCP",//协议
          port: 8080,//服务端口
          targetPort: 8080,//pod端口
          nodePort: 5000,  //节点端口
          nodePortAutoCreate: true //节点端口自动生成
        }]
      },
      rules1: {
      },
    }
  },
  methods: {
    appNameInputBlur: function(event) {
      this.form1.name = "service-" + event.target.value;
    },

    removeDomain(item) {
      var index = this.form1.servicePorts.indexOf(item)
      if (index != -1) {
        this.form1.servicePorts.splice(index, 1)
      }
    },
    addDomain() {
      this.form1.servicePorts.push({
        name: '',//端口名称
        protocal: "TCP",//协议
        port: 8080,//服务端口
        targetPort: 8080,//pod端口
        nodePort: 5000,  //节点端口
        nodePortAutoCreate: true //节点端口自动生成
      });
    },

    //服务查询
    serviceQuery() {
      let currentNs = this.userBaseInfo.getCurrentSelectedNamespace();
      let url = this.projectConfig.URL_API_APP_MANAGE_APP_SERVICE_LIST_BY_NAMESPACE;
      url += "?namespace=" + currentNs + "&queryKey=" + this.queryKey;
      // 开启遮罩
      this.loadingDataTable = true;
      this.httpClient.httpClientget(url).then((response) => {
        // 遮罩结束
        this.loadingDataTable = false;
        let data = response.data;
        this.serviceData = data;
      }).catch(error => {
        // 遮罩结束
        this.loadingDataTable = false;
      });
    },

    //新增服务窗口开启
    addServiceDialogOpen() {
      this.vShow = true;
      let currentNs = this.userBaseInfo.getCurrentSelectedNamespace();
      let url = this.projectConfig.URL_API_APP_MANAGE_QUERY;
      url += "?namespace=" + currentNs + "&page=1&pageSize=1000&queryKey=&queryStatus=all";
      this.httpClient.httpClientget(url).then((response) => {
        let data = response.data;
        this.serviceTitle = "新增服务(slb)";
        this.serviceNameDisable = false;
        this.baseBackendAppSelect = true;
        let r = {//服务form
          selectAppNameKube: "",
          apps: data.items,
          type: 'ClusterIP',
          name: '',//服务名称
          backendApp: '',//后端应用
          sessionAffinity: 'None',//服务负载均衡策略
          selectors: {},//服务后端应用选择器
          servicePorts: [{
            name: '',//端口名称
            protocal: "TCP",//协议
            port: 8080,//服务端口
            targetPort: 8080,//pod端口
            nodePort: 5000,  //节点端口
            nodePortAutoCreate: true //节点端口自动生成
          }]
        };
        this.form1 = r;
        this.serviceAddVisible = true;
      }).catch(error => {
      });
    },

    //新增/修改服务创建提交
    addOrUpdateServiceSubmit() {
      //校验
      if (this.form1.backendApp == '') {
        this.$message({
          message: '后端应用不能为空!',
          type: 'warning'
        });
        return;
      }
      if (this.form1.name == '') {
        this.$message({
          message: '服务名称不能为空!',
          type: 'warning'
        });
        return;
      }
      if (this.form1.servicePorts.length == 0) {
        this.$message({
          message: '至少需要一个端口映射!',
          type: 'warning'
        });
        return;
      }
      // 遮罩开始
      const loading = this.$loading({ body: true });
      let currentNs = this.userBaseInfo.getCurrentSelectedNamespace();
      let parm = {
        annotations: {},
        clusterIP: "None",
        creationTimestamp: "",
        labels: { service: this.form1.name },
        name: this.form1.name,
        namespace: currentNs,
        selectors: { app: this.form1.backendApp },
        servicePorts: this.form1.servicePorts,
        sessionAffinity: this.form1.sessionAffinity,
        status: {},
        type: this.form1.type,
        uid: "001"
      };
      if(this.vShow){
        this.userBaseInfo.setOperObjectName("新增服务:"+parm.name);
      }else{
        this.userBaseInfo.setOperObjectName("修改服务"+parm.name);
      }
      
      this.httpClient.httpClientPost(this.projectConfig.URL_API_APP_MANAGE_APP_SERVICE_2, parm).then(res => {
        // 遮罩结束
        loading.close();
        let r = res.data;
        if (r) {
          this.serviceAddVisible = false;
          this.serviceQuery();
        } else {
          this.$message({
            message: '新增服务失败!',
            type: 'warning'
          });
        }
      })
    },


    //修改服务窗口开启
    updateServiceDialogOpen: function(index, row) {
      this.vShow = false;
      this.baseBackendAppSelect = true;
      this.serviceTitle = "修改服务(slb)";
      this.serviceNameDisable = true;
      let r = {//服务form
        backendApp: row.selectors.app,
        type: row.type,
        name: row.name,//服务名称
        sessionAffinity: row.sessionAffinity,//服务负载均衡策略
        servicePorts: row.servicePorts
      };
      this.form1 = r;
      this.serviceAddVisible = true;
    },

    //后端应用选择变更
    appSelectChange: function(value) {
      this.form1.name = "service-" + value;
      this.form1.backendApp = value;
    },

    // 删除服务
    deleteService: function(index, row) {
      this.$confirm("此操作将永久删除此服务, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          let url = this.projectConfig.URL_API_APP_MANAGE_APP_SERVICE;
          url += "/" + row.namespace + "/" + row.name;
          this.userBaseInfo.setOperObjectName("删除服务:"+row.name);
          this.httpClient.httpClientDelete(url).then((response) => {
            this.serviceQuery();
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消操作"
          });
        });
    },
    format1: function(row, column, cellValue) {
      if (cellValue == 'None') {
        return "轮询";
      }
      return "session";
    },
    format2: function(row, column, cellValue) {
      if (cellValue == 'NodePort') {
        return "外部访问";
      }
      return "内部访问";
    },
    format4: function(row, column, cellValue) {
      return cellValue.app;
    },
    format5(row) {
      let sps = row.servicePorts;
      let rs = "";
      sps.forEach(function(e) {
        if (rs != '') {
          rs += "<br>";  //换行符
        }
        rs += row.name + "." + row.namespace + ":" + e.port;
      });
      return rs;
    },
    format6(row) {
      let sps = row.servicePorts;
      let rs = "";
      sps.forEach(function(e) {
        if (e.nodePort != 0) {
          if (rs != '') {
            rs += "<br>";  //换行符
          }
          rs += "节点ip:" + e.nodePort;
        }
      });
      return rs;
    },
    format7: function(row, column, cellValue) {
      return "2天前";
    }
  },
  mounted: function() {
    this.serviceQuery();
  },
  computed: {
    getCurrentNamespace() {
      return this.$store.getters.namespace;
    }
  },
  watch: {
    getCurrentNamespace(val) {
      this.serviceQuery();
    },

  }
}
</script>

<style>
.service .el-table tr {
  text-align: center;
}

.service .el-time {
  border: 1px solid;
  border-radius: 4px;
}

.service .el-width {
  width: 400px;
}

.service .el-bar {
  padding-bottom: 50px;
}

.service .el-bar .nbd {
  border-bottom: none;
}

.service .el-dialog__header {
  padding: 20px 20px 10px;
  border-bottom: 1px solid #ccc;
}

.service el-icon-search {
  border: 1px solid #eaeaea;
  border-radius: 4px;
}

.service .search .el-input {
  border: 1px solid #eaeaea;
}

.service .el-date-editor--datetimerange {
  border: 1px solid #eaeaea;
  border-radius: 4px;
}

.service .el-table .cell {
  padding: 0;
}
</style>